package com.dhcc.ws.controller;

import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.wsdl.WSDLException;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;

import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.dhcc.ws.bean.ParameterInfo;
import com.dhcc.ws.bean.vo.InputRequest;
import com.dhcc.ws.bean.vo.OutputResponse;
import com.dhcc.ws.common.entity.Result;
import com.dhcc.ws.common.entity.ResultCode;
import com.dhcc.ws.util.SoapClient;
import com.dhcc.ws.util.WAWsdlUtil;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
* <p>标题: WsCallController.java</p>
* <p>业务描述:健康管理平台</p>
* <p>公司:东华软件股份公司</p>
* <p>版权:dhcc2013</p>
* @author 胡凯
* @date 2019年12月9日
* @version V1.0 
*/
@RestController
@RequestMapping("/dhccApi/ws")
@Api(value  = "webservice请求模块")
public class WsCallController {

	/**
	 * 
	* 方法名:          getWsMethond
	* 方法功能描述:    获取webservice方法
	* @param:         url
	* @return:        其他非简体汉字返回 '0';
	* @Author:        胡凯
	* @Create Date:   2019年12月9日 下午2:37:51
	 */
	@ApiOperation(value="getWsMethond",tags = "获取webservice方法")
    @RequestMapping(value="/getWsMethond",method = RequestMethod.GET)
	public Result getWsMethond(InputRequest inputRequest) {
        List<String> operations = new ArrayList<String>();
        try {
			WAWsdlUtil.getOperationList(inputRequest.getUrl(), operations);
		} catch (WSDLException e) {
			e.printStackTrace();
		}
		return new Result(ResultCode.SUCCESS,operations);
	}
	
	/**
	 * 
	* 方法名:          getMethodParams
	* 方法功能描述:    获取webservice方法入参
	* @param:         url methond
	* @return:        其他非简体汉字返回 '0';
	* @Author:        胡凯
	* @Create Date:   2019年12月9日 下午2:38:07
	 */
	@ApiOperation(value="getMethodParams",tags = "获取webservice方法入参")
    @RequestMapping(value="/getMethodParams",method = RequestMethod.GET)
	public Result getMethodParams(InputRequest inputRequest) {
		List<ParameterInfo> parameterInfos = new ArrayList<ParameterInfo>();
        try {
        	parameterInfos = WAWsdlUtil.getMethodParams(inputRequest.getUrl(), inputRequest.getMethod());
		} catch (WSDLException e) {
			e.printStackTrace();
		}
		return new Result(ResultCode.SUCCESS,parameterInfos);
	}
	
	/**
	 * 
	* 方法名:          getMethodParams
	* 方法功能描述:    获取webservice方法返回参数
	* @param:         url methond
	* @return:        其他非简体汉字返回 '0';
	* @Author:        胡凯
	* @Create Date:   2019年12月9日 下午2:38:07
	 */
	@ApiOperation(value="getMethodReturn",tags = "获取webservice方法返回参数")
	@RequestMapping(value="/getMethodReturn",method = RequestMethod.GET)
	public Result getMethodReturn(InputRequest inputRequest) {
		List<ParameterInfo> parameterInfos = new ArrayList<ParameterInfo>();
		try {
			parameterInfos = WAWsdlUtil.getMethodReturn(inputRequest.getUrl(), inputRequest.getMethod());
		} catch (WSDLException e) {
			e.printStackTrace();
		}
		return new Result(ResultCode.SUCCESS,parameterInfos);
	}
	@ApiOperation(value="getTargetNameSpace",tags = "获取TargetNameSpace")
	@RequestMapping(value="/getTargetNameSpace",method = RequestMethod.GET)
	public Result getTargetNameSpace(InputRequest inputRequest) {
		String targetNamespace = "";
		try {
			targetNamespace = WAWsdlUtil.getTargetNamespace(inputRequest.getUrl());
		} catch (WSDLException e) {
			e.printStackTrace();
		}
		return new Result(ResultCode.SUCCESS,targetNamespace);
	}
	
	/**
	 * 
	* 方法名:          analysisWs
	* 方法功能描述:    通过wsdl地址，解析webservice方法，入参，返回参数
	* @param:         是包含汉字的字符串
	* @return:        其他非简体汉字返回 '0';
	 * @throws WSDLException 
	* @Author:        胡凯
	* @Create Date:   2019年12月9日 下午2:39:38
	 */
	@ApiOperation(value="analysisWs",tags = "通过wsdl地址，解析webservice方法，入参，返回参数")
	@RequestMapping(value="/analysisWs",method = RequestMethod.GET)
	public Result analysisWs(InputRequest inputRequest) throws WSDLException {
		String url = inputRequest.getUrl();
		List<String> operations = new ArrayList<String>();
	    WAWsdlUtil.getOperationList(url, operations);
	    String targetNamespace =  WAWsdlUtil.getTargetNamespace(url);
	    Map<String, Map<String, List<ParameterInfo>>> requestMap = new HashMap<String, Map<String,List<ParameterInfo>>>();
        for (String operationName : operations) {
        	Map<String, List<ParameterInfo>> argsMap = new HashMap<String, List<ParameterInfo>>();
            List<ParameterInfo> parameterInfos = WAWsdlUtil.getMethodParams(url, operationName);
            argsMap.put("in", parameterInfos);
            List<ParameterInfo> returnInfos = WAWsdlUtil.getMethodReturn(url, operationName);
            argsMap.put("out", returnInfos);
            requestMap.put(operationName, argsMap);
        }
		return new Result(ResultCode.SUCCESS,new OutputResponse(requestMap,targetNamespace));
	}
	
	/**
	 * 
	* 方法名:          callWs
	* 方法功能描述:    动态调用webservice
	* @param:         url,method,入参，返回参数格式
	* @return:        其他非简体汉字返回 '0';
	 * @throws SOAPException 
	 * @throws MalformedURLException 
	* @Author:        胡凯
	* @Create Date:   2019年12月9日 下午2:46:24
	 */
	@ApiOperation(value="callWs",tags = "调用webservice")
	@RequestMapping(value="/callWs",method = RequestMethod.GET)
	public @ResponseBody Result callWs(InputRequest inputRequest) throws SOAPException, MalformedURLException  {
		String url = inputRequest.getUrl();
		String method = inputRequest.getMethod();
		String namespaceURI = inputRequest.getNamespaceURI();
		Map<String, String> args = inputRequest.getArgs();
		String parmkey = inputRequest.getParmKey();
		String parmName = inputRequest.getParmName();
		String responseFormat = inputRequest.getResponseFormat();
		String parmHeader = inputRequest.getParmHeader();
//		String result = WsCallUtil.callService(url, method, requestOne);
		SoapClient client = SoapClient.create(url);
		
		client.setCharset(CharsetUtil.CHARSET_GBK);
		client.setMethod(method,namespaceURI);
//		client.setParam(parmkey,parmName);
		//cxf有问题，需要验证--webservice发布时，方法参数需要带targetNamespace
		if(!StrUtil.isEmpty(parmkey)) {
			client.setParam(parmkey,parmName,false);
		}
		//有问题，需要验证
		if(!StrUtil.isEmpty(parmHeader)) {
			String authType = inputRequest.getAuthType();
			if(authType.equals("httpHeaders")) {
				//httpHeaders
				HashMap<String, String> headers = new HashMap<String, String>();
				headers.put("Authorization", "Basic YWRtaW46MTIzNDU2");
				client.setHttpHeaders(headers);
			}else {
				//soapHeaders,请处理这个
				 String username = "admin";
			     String password = "123456";
		        SOAPMessage soapmessage =  client.getSOAPHeader(namespaceURI,username,password);
		        client.setSOAPMessage(soapmessage);
		       // client.setHeader(new QName(namespaceURI,namespaceURI));

			}

		}
		//参数遍历
		//设置参数
		if(args!=null) {
			Iterator<String> iters = args.keySet().iterator();
			while (iters.hasNext()) {
				String key = iters.next();
				String value = args.get(key);
				client.setParam(key,value);
			}
		}
		String response = client.send(true);//response处理
		return new Result(ResultCode.SUCCESS,getResult(response, responseFormat));
	}
	
	private String getResult(String responseStr,String responseFormat) {
		if(responseStr!=null
				&&responseFormat!=null
				&&!responseStr.contains(responseFormat)) {
			return responseStr;
		}
		String startIndex = "<"+responseFormat+">";
		String endIndex   = "</"+responseFormat+">";
		int s= responseStr.indexOf(startIndex);
		int e = responseStr.lastIndexOf(endIndex);
		e = e+endIndex.length();
		String result = responseStr.substring(s, e);
		return result;
	}
	
}
